package com.buddy.learn.algorithm.demo;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Buddy
 * @date 2021/5/6
 */
public class _018识别有效的IP地址和掩码并进行分类统计 {
    /**
     * 请解析IP地址和对应的掩码，进行分类识别。要求按照A/B/C/D/E类地址归类，不合法的地址和掩码单独归类。
     * 所有的IP地址划分为 A,B,C,D,E五类
     * A类地址1.0.0.0~126.255.255.255;
     * B类地址128.0.0.0~191.255.255.255;
     * C类地址192.0.0.0~223.255.255.255;
     * D类地址224.0.0.0~239.255.255.255；
     * E类地址240.0.0.0~255.255.255.255
     * 私网IP范围是：
     * 10.0.0.0～10.255.255.255
     * 172.16.0.0～172.31.255.255
     * 192.168.0.0～192.168.255.255
     * 子网掩码为二进制下前面是连续的1，然后全是0。（例如：255.255.255.32就是一个非法的掩码）
     * 注意二进制下全是1或者全是0均为非法
     * 注意：
     * 1. 类似于【0.*.*.*】和【127.*.*.*】的IP地址不属于上述输入的任意一类，也不属于不合法ip地址，计数时可以忽略
     * 2. 私有IP地址和A,B,C,D,E类地址是不冲突的
     * 输入：
     * 多行字符串。每行一个IP地址和掩码，用~隔开。
     * 输出：
     * 统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数，之间以空格隔开。
     * 例如：
     * 10.70.44.68~255.254.255.0
     * 1.0.0.1~255.0.0.0
     * 192.168.0.2~255.255.255.0
     * 19..0.~255.255.255.0
     * <p>
     * 1 0 1 0 0 2 1
     */

    public static void main(String[] args) {
//        Scanner in = new Scanner(System.in);
//        List<String> strList = new ArrayList<>();
//        String result = "";
//        while (in.hasNext()) {
//            String str = in.nextLine();
//            strList.add(str);
//            result = getCount(strList);
//        }
        List<String> list = new ArrayList<>();
        list.add("10.70.44.68~255.254.255.0");
        list.add("1.0.0.1~255.0.0.0");
        list.add("192.168.0.2~255.255.255.0");
        list.add("19..0.~255.255.255.0");
        String result = getCount(list);
        System.out.println(result);

    }

    private static String getCount(List<String> list) {
        int a = 0, b = 0, c = 0, d = 0, e = 0, error = 0, prit = 0;
        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            String ip = str.substring(0, str.indexOf("~"));
            String dns = str.substring(str.indexOf("~") + 1);
            //判断子网掩码
            String[] dnss = dns.split("\\.");
            //判断ip
            String[] ips = ip.split("\\.");
            int ip1, ip2, ip3, ip4;
            int dns1, dns2, dns3, dns4;
            String dns5;
            try {
                ip1 = Integer.valueOf(ips[0]);
                ip2 = Integer.valueOf(ips[1]);
                ip3 = Integer.valueOf(ips[2]);
                ip4 = Integer.valueOf(ips[3]);
                dns1 = Integer.valueOf(dnss[0]);
                dns2 = Integer.valueOf(dnss[1]);
                dns3 = Integer.valueOf(dnss[2]);
                dns4 = Integer.valueOf(dnss[3]);
                dns5 = leftPade(Integer.toBinaryString(dns1))
                        + leftPade(Integer.toBinaryString(dns2))
                        + leftPade(Integer.toBinaryString(dns3))
                        + leftPade(Integer.toBinaryString(dns4));
                System.out.println(str + " " + dns5);
            } catch (Exception exception) {
                error += 1;
                continue;
            }
            //判断子网掩码是否正确
            int a1 = dns5.indexOf("1");
            int b1 = dns5.lastIndexOf("1");
            //子网掩码全是1 非法 || 子网掩码全是0 非法
            if (b1 == dns5.length() - 1 || b1 == -1) {
                error += 1;
                continue;
            }
            String tmpDns = dns5.substring(a1, b1);
            int c1 = tmpDns.indexOf("0");
            // 1 中间如果有0 非法
            if (c1 != -1) {
                error += 1;
                continue;
            }
            if (ip1 > 0 && ip1 < 127) {
                // A类地址1.0.0.0~126.255.255.255;
                // 私网地址1：10.0.0.0~10.255.255.255
                if (ip1 == 10) {
                    prit += 1;
                }
                a += 1;
            } else if (ip1 > 127 && ip1 < 192) {
                // B类地址128.0.0.0 ~ 191.255.255.255;
                // 私网地址2：172.16.0.0~172.31.255.255
                if (ip1 == 172 && ip2 >= 16 && ip2 <= 31) {
                    prit += 1;
                }
                b += 1;
            } else if (ip1 > 191 && ip1 < 224) {
                // C类地址192.0.0.0~223.255.255.255;
                // 私网地址： 192.168.0.0～192.168.255.255
                if (ip1 == 192 && ip2 == 168) {
                    prit += 1;
                }
                c += 1;
            } else if (ip1 > 223 && ip1 < 240) {
                // D类地址224.0.0.0~239.255.255.255；
                d += 1;
            } else if (ip1 > 239 && ip1 < 260) {
                // E类地址240.0.0.0~255.255.255.255
                e += 1;
            }
        }
        return a + " " + b + " " + c + " " + d + " " + e + " " + error + " " + prit;
    }

    private static String leftPade(String str) {
        String result = "";
        if (str.length() < 8) {
            for (int i = 0; i < 8 - str.length(); i++) {
                result = "0" + str;
            }
        } else {
            result = str;
        }
        return result;
    }
}
